
# pip install aiortc

from flask import Flask, render_template, send_from_directory
from flask_socketio import SocketIO, emit
from multiprocessing import Process, Manager, cpu_count
import os
import cv2
import base64
import time
from camera_stream import CameraStream
import zlib

os.environ['OPENCV_LOG_LEVEL'] = 'SILENT'

app = Flask(__name__)
socketio = SocketIO(app)
camera_ids = []


def find_cameras(max_tested=10):
    available_cameras = []

    for i in range(max_tested):
        cap = cv2.VideoCapture(i)
        if cap.isOpened():
            print('------------------------------------')
            print(f"Camera ID: {i}")
            print(f"Frame width: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}")
            print(f"Frame height: {cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
            print(f"FPS: {cap.get(cv2.CAP_PROP_FPS)}")
            print()
            if i==0: #skip the first camera, it is the default camera of the computer
                continue

            available_cameras.append(i)
            cap.release()

    global camera_ids
    camera_ids = available_cameras
    return available_cameras



def start_camera_stream(camera_id, camera_feeds):
    stream = CameraStream(camera_id)
    while True:
        frame = stream.get_frame()
        if frame is not None:
            _, buffer = cv2.imencode('.jpg', frame)
            # _, buffer = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
            frame_data = buffer.tobytes()
            # frame_encoded = base64.b64encode(frame_data).decode('utf-8')
            # print(f'Camera {camera_id} frame size: {len(frame_encoded)}')
            # camera_feeds[camera_id] = frame_encoded
            camera_feeds[camera_id] = frame_data
            time.sleep(0.1)  # 控制推流帧率


@app.route('/')
def index():
    print('index')
    print(camera_ids)
    return render_template('app1.html', camera_ids=camera_ids)


@socketio.on('request_camera_feeds')
def handle_camera_feeds_request():
    socketio.emit('camera_feeds', dict(camera_feeds))


@app.route('/snapshot')
def snapshot():
    print('Saving snapshots...')
    directory = 'snapshots'
    if not os.path.exists(directory):
        os.makedirs(directory)
    for camera_id, frame in camera_feeds.items():
        # img_data = base64.b64decode(frame)
        img_data = frame    
        timestamp = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
        filename = os.path.join(directory, f'camera_{camera_id}_{timestamp}.jpg')
        with open(filename, 'wb') as f:
            f.write(img_data)
    return 'Snapshots saved!'



if __name__ == '__main__':
    # judge the operating system
    if os.name == 'nt':
        print('Windows')
        # Start mode on windows
        manager = Manager()
        camera_feeds = manager.dict()  # 存储所有摄像头推流数据
        processes = []

        cameras = find_cameras()
        print(f'Found {len(cameras)} camera(s)')
        print(cameras)
        num_cameras = len(cameras)
        for camera_id in cameras:
            p = Process(target=start_camera_stream, args=(camera_id, camera_feeds))
            # processes.append(p)
            p.daemon = True
            p.start()
        
        # socketio.run(app, debug=True)
        socketio.run(app, debug=True, use_reloader=False,port=5166)
    else:
        print('Linux')
        # Start mode on Linux
        manager = Manager()
        camera_feeds = manager.dict()  # 存储所有摄像头推流数据

        processes = []
        cameras = find_cameras()

        print(f'Found {len(cameras)} camera(s)')
        print(cameras)
        num_cameras = len(cameras)
        for camera_id in cameras:
            p = Process(target=start_camera_stream, args=(camera_id, camera_feeds))
            processes.append(p)
            p.start()


        socketio.run(app, debug=True, use_reloader=False,port=5166)



